package com.sneakxy.mybase4j.platform.controller;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.sneakxy.mybase4j.base.bean.ValidAdd;
import com.sneakxy.mybase4j.base.bean.ValidEdit;
import com.sneakxy.mybase4j.base.controller.BaseController;
import com.sneakxy.mybase4j.platform.beans.Dict;
import com.sneakxy.mybase4j.platform.service.IDictService;
import com.sneakxy.mybase4j.util.BeanHelper;
import com.sneakxy.mybase4j.util.DataGrid;
import com.sneakxy.mybase4j.util.PageSearch;
import com.sneakxy.mybase4j.util.Response;
import com.sneakxy.mybatis.commons.repository.query.domain.CriteriaBuilder;

/**
 * 数据字典管理
 * @author 潜行的青衣
 * @see
 */
@RestController
@RequestMapping("/api/dict/")
public class DictController extends BaseController {

	@Resource
	private IDictService dictService;
	
	@RequiresPermissions("sys:dict:manager")
	@RequestMapping("datagrid")
	public DataGrid<Dict> datagrid(PageSearch search) {
		if(StringUtils.isBlank(search.getSortName())) {
			search.setSortName("sort");
		}
		return new DataGrid<Dict>(dictService.findBySearch(null, search.getSearchText(), search.toPageable()));
	}
	
	@RequiresPermissions("sys:dict:manager:value")
	@RequestMapping("value/datagrid")
	public DataGrid<Dict> datagrid(PageSearch search, String parent_id) {
		if(StringUtils.isBlank(search.getSortName())) {
			search.setSortName("sort");
		}
		return new DataGrid<Dict>(dictService.findBySearch(StringUtils.trimToNull(parent_id), search.getSearchText(), search.toPageable()));
	}
	
	
	@RequiresPermissions("sys:dict:manager:add")
	@RequestMapping("add")
	public Response add(@Validated(ValidAdd.class) Dict dict, BindingResult result) {
		if(result.hasErrors()) {
			return this.getFieldErrorsResponse(result);
		}
		if(!this.validate(dict.getValue())) {
			return new Response(false, 1);
		}
		//去空格
		BeanHelper.trimToEmpty(dict);
		dict.setParentId(null);
		dict.setId(null);
		
		this.dictService.save(dict);
		return new Response(true);
	}
	
	@RequiresPermissions("sys:dict:manager:edit")
	@RequestMapping("edit")
	public Response edit(@Validated(ValidEdit.class) Dict dict, BindingResult result) {
		if(result.hasErrors()) {
			return this.getFieldErrorsResponse(result);
		}
		if(!this.validateEdit(dict.getId(), dict.getValue())) {
			return new Response(false, 1);
		}
		//去空格
		BeanHelper.trimToEmpty(dict);
		dict.setParentId(null);
		
		this.dictService.save(dict);
		return new Response(true, dict);
	}
	
	@RequiresPermissions("sys:dict:manager:value:add")
	@RequestMapping("value/add")
	public Response valueAdd(@Validated(ValidAdd.class) Dict dict, BindingResult result) {
		if(result.hasErrors()) {
			return this.getFieldErrorsResponse(result);
		}
		if(!this.validate(dict.getParentId(), dict.getValue())) {
			return new Response(false, 1);
		}
		//去空格
		BeanHelper.trimToEmpty(dict);
		dict.setId(null);
		
		this.dictService.save(dict);
		return new Response(true);
	}
	
	@RequiresPermissions("sys:dict:manager:value:edit")
	@RequestMapping("value/edit")
	public Response valueEdit(@Validated(ValidEdit.class) Dict dict, BindingResult result) {
		if(result.hasErrors()) {
			return this.getFieldErrorsResponse(result);
		}
		Dict old = this.dictService.findOne(dict.getId());
		if(!this.validateEdit(dict.getId(), old.getParentId(), dict.getValue())) {
			return new Response(false, 1);
		}
		//去空格
		BeanHelper.trimToEmpty(dict);
		dict.setParentId(old.getParentId());
		
		this.dictService.save(dict);
		return new Response(true, dict);
	}
	
	@RequiresPermissions("sys:dict:manager:add")
	@RequestMapping("validate")
	public Boolean validate(String value) {
		Dict old = this.dictService.findByType(value, false);
		return old == null;
	}
	
	@RequiresPermissions("sys:dict:manager:value:add")
	@RequestMapping("value/validate")
	public Boolean validate(String parent_id, String value) {
		Dict old = this.dictService.findByType(parent_id, value, false);
		return old == null;
	}
	
	@RequiresPermissions("sys:dict:manager:edit")
	@RequestMapping("validateEdit")
	public Boolean validateEdit(String id, String value) {
		CriteriaBuilder<Dict> builder = new CriteriaBuilder<Dict>(Dict.class);
		builder.andNotEq("id", id);
		builder.andEq("value", value);
		builder.andIsNull("parentId");
		return this.dictService.count(builder.build()) == 0;
	}
	
	@RequiresPermissions("sys:dict:manager:value:edit")
	@RequestMapping("value/validateEdit")
	public Boolean validateEdit(String id, String parent_id, String value) {
		CriteriaBuilder<Dict> builder = new CriteriaBuilder<Dict>(Dict.class);
		builder.andNotEq("id", id);
		builder.andEq("value", value);
		builder.andEq("parentId", parent_id);
		return this.dictService.count(builder.build()) == 0;
	}
	
	@RequiresPermissions(
		value = {"sys:dict:manager:remove", "sys:dict:manager:value:remove"}, 
		logical = Logical.OR
	)
	@RequestMapping("remove")
	public Response remove(String[] ids) {
		int success = 0;
		int all = 0;
		List<Integer> result = new ArrayList<Integer>();
		if(ids != null) {
			all = ids.length;
			for(String id: ids) {
				if(!this.dictService.hasChildren(id)) {
					this.dictService.delete(id);
					success ++;
				}
			}
		}
		result.add(all);
		result.add(success);
		result.add(all - success);
		return new Response(true, result);
	}
	
}
